package com.simple.relaxed.agent;

import com.simple.relaxed.anno.TaskMethod;
import com.simple.relaxed.constant.Constant;
import ohos.app.Context;
import ohos.app.dispatcher.task.TaskPriority;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 此对象为任务增强处理器，被此对象增强的对象，可以通过指定注解，将指定的方法，作为一个Runnable对象，扔到指定的堆栈中执行，这里目前只提供UI与非UI两个堆栈
 */
public class TaskHandler implements InvocationHandler {

    /**
     * 被代理增强的对象
     */
    private Object instance;

    /**
     * 上下文对象，此对象必不可少，UI与非UI堆栈，都是通过此对象获取的
     */
    private Context context;

    public TaskHandler(Context context, Object object) {
        super();
        instance = object;
        this.context = context;
    }

    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
        TaskMethod taskMethod = method.getDeclaredAnnotation(TaskMethod.class);
        if (taskMethod == null) {
            if (objects == null) {
                return method.invoke(instance);
            }
            return method.invoke(instance, objects);
        }
        int stackFlag = taskMethod.stackFlag();
        if (Constant.UI_STACK == stackFlag) {
            context.getUITaskDispatcher().asyncDispatch(() -> {
                try {
                    if (objects == null) {
                        method.invoke(instance);
                    } else {
                        method.invoke(instance, objects);
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            });
        } else if (Constant.OTHER_STACK == stackFlag) {
            context.getGlobalTaskDispatcher(TaskPriority.DEFAULT).asyncDispatch(() -> {
                try {
                    if (objects == null) {
                        method.invoke(instance);
                    } else {
                        method.invoke(instance, objects);
                    }
                } catch (IllegalAccessException | InvocationTargetException e) {
                    e.printStackTrace();
                }
            });
        }
        return null;
    }
}
